package com.example.socket.core;

import com.example.socket.utils.ByteUtils;
import io.netty.buffer.ByteBuf;

import java.util.Objects;

/**
 * 通信指令
 *
 * @author frank
 */
public class Command {

    /** 指令所属模块 */
    private short module;
    /** 指令标识 */
    private short command;

    public static Command valueOf(ByteBuf buff) {
        Command result = new Command();
        result.module = buff.readShort();
        result.command = buff.readShort();
        return result;
    }

    /**
     * 创建通信指令对象实例
     * @param command 指令标识
     * @param modules 所属模块标识
     * @return
     */
    public static Command valueOf(short module, short command) {
        Command result = new Command();
        result.module = module;
        result.command = command;
        return result;
    }

    /**
     * 创建通信指令对象实例
     * @param bytes 原始通信信息数组
     * @param start 开始位置
     * @param end 结束位置
     * @return
     */
    public static Command valueOf(byte[] bytes, int start) {
        short module = ByteUtils.shortFromByte(bytes, start);
        short command = ByteUtils.shortFromByte(bytes, start + 2);
        return valueOf(module, command);
    }

    /**
     * 将当前对象转换为通信表示格式
     * @return
     */
    public byte[] toBytes() {
        byte[] result = new byte[4];
        ByteUtils.shortToByte(module, result, 0);
        ByteUtils.shortToByte(command, result, 2);
        return result;
    }

    // Getter and Setter ...

    public short getModule() {
        return module;
    }

    public short getCommand() {
        return command;
    }

    @Override
    public String toString() {
        return "M:" + this.module + " C:" + this.command;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Command command1 = (Command) o;
        return module == command1.module &&
                command == command1.command;
    }

    @Override
    public int hashCode() {
        return Objects.hash(module, command);
    }

    public void setModule(short module) {
        this.module = module;
    }

    public void setCommand(short command) {
        this.command = command;
    }
}